package com.damai.action;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.citywithincity.db.Db;
import com.damai.action.aop.Invoker;
import com.damai.action.meta.ApiMetaData;
import com.damai.lang.Lang;
import com.damai.mvc.view.ErrorRender;

public class ApiAction implements IApiAction {

	private IParamParser parser;
	private Invoker invoker;
	@SuppressWarnings("rawtypes")
	private IRender render;
	private ApiMetaData metaData;
	private ErrorRender errorRender;
	private String key;
	private Class<?> controllerClass;
	private Method method;
	private String[] params;

	@SuppressWarnings("rawtypes")
	public ApiAction(IParamParser parser, Invoker invoker, IRender render, ErrorRender errorRender, String key,
			ApiMetaData metaData, Class<?> controllerClass, Method method, String[] params) {
		this.parser = parser;
		this.invoker = invoker;
		this.render = render;
		this.metaData = metaData;
		this.key = key;
		this.errorRender = errorRender;
		this.controllerClass = controllerClass;
		this.method = method;
		this.params = params;
	}

	public Invoker getInvoker() {
		return invoker;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void doFilter(HttpServletRequest request, HttpServletResponse response) throws IOException {
		final IParamParser parser = this.parser;
		final IRender render = this.render;
		try {
			Object[] args = parser.parseParam(request);
			Object result = invoker.invoke(request, args);
			render.render(this, result, request, response);
		} catch (Throwable ex) {
			
			errorRender.renderError(Lang.getCourse(ex), request, response);
		} finally {
			Db.release();
		}
	}

	@Override
	public String getKey() {
		return key;
	}

	@Override
	public ApiMetaData getMetaData() {
		return metaData;
	}

	public void setInvoker(Invoker invoker) {
		this.invoker = invoker;
	}

	public String[] getParams() {
		return params;
	}

	public void setParams(String[] params) {
		this.params = params;
	}

	public Class<?> getControllerClass() {
		return controllerClass;
	}

	public void setControllerClass(Class<?> controllerClass) {
		this.controllerClass = controllerClass;
	}

	public Method getMethod() {
		return method;
	}

	public void setMethod(Method method) {
		this.method = method;
	}

}
